~ chicken-core (chicken-5) /manual/Module (chicken process)


  1[[tags: manual]]
  2[[toc:]]
  3
  4== Module (chicken process)
  5
  6This module offers procedures for interacting with subprocesses.
  7
  8* New in CHICKEN 5.4.0: Errors caused by underlying C calls that
  9  change errno will produce a condition object with an {{errno}}
 10  property, which can be accessed with
 11  {{(get-condition-property <the-condition-object> 'exn 'errno)}}.
 12
 13=== Processes
 14
 15==== process-execute
 16
 17<procedure>(process-execute PATHNAME [ARGUMENT-LIST [ENVIRONMENT-ALIST]])</procedure>
 18
 19Replaces the running process with a new process image from the program
 20stored at {{PATHNAME}}, using the C library function {{execvp(3)}}.
 21If the optional argument {{ARGUMENT-LIST}} is given, then it should
 22contain a list of strings which are passed as arguments to the subprocess.
 23If the optional argument {{ENVIRONMENT-ALIST}} is supplied, then the library
 24function {{execve(2)}} is used, and the environment passed in
 25{{ENVIRONMENT-ALIST}} (which should be of the form {{(("<NAME>" . "<VALUE>") ...)}})
 26is given to the invoked process. Note that {{execvp(3)}} respects the
 27current setting of the {{PATH}} environment variable while {{execve(3)}} does not.
 28
 29This procedure never returns; it either replaces the process with a new one
 30or it raises an exception in case something went wrong executing the program.
 31
 32On Windows, these procedures all have an additional optional parameter
 33{{EXACT-FLAG}}, which defaults to {{#f}}. When {{#f}} is passed, any
 34argument string with embedded whitespace will be wrapped in
 35quotes. When {{#t}} no such wrapping occurs.
 36
 37
 38==== process-fork
 39
 40<procedure>(process-fork [THUNK [KILLOTHERS?]])</procedure>
 41
 42Creates a new child process with the UNIX system call
 43{{fork()}}. Returns either the PID of the child process or 0. If
 44{{THUNK}} is given, then the child process calls it as a procedure
 45with no arguments and terminates. If {{THUNK}} is given and the
 46optional argument {{KILLOTHERS?}} is true, then kill all other
 47existing threads in the child process, leaving only the current thread
 48to run {{THUNK}} and terminate.
 49
 50'''NOTE''': On native Windows builds (all except cygwin), this
 51procedure is unimplemented and will raise an error.
 52
 53==== process-run
 54
 55<procedure>(process-run COMMANDLINE)</procedure><br>
 56<procedure>(process-run COMMAND ARGUMENT-LIST)</procedure>
 57
 58Creates a new child process. The PID of the new process is returned.
 59
 60* The single parameter version passes the {{COMMANDLINE}} to the
 61system shell, so usual argument expansion can take place.  Be careful
 62to properly quote arguments with the {{qs}} procedure to avoid shell
 63injection vulnerabilities.
 64* The multiple parameter version directly invokes the {{COMMAND}} with
 65the {{ARGUMENT-LIST}}, and is vastly preferred over the
 66single-parameter version because of its better safety.
 67
 68==== process-signal
 69
 70<procedure>(process-signal PID [SIGNAL])</procedure>
 71
 72Sends {{SIGNAL}} to the process with the id {{PID}} using the
 73UNIX system call {{kill()}}. {{SIGNAL}} defaults to the value
 74of the variable {{signal/term}}.
 75
 76'''NOTE''': On native Windows builds (all except cygwin), this
 77procedure is unimplemented and will raise an error.
 78
 79==== process-spawn
 80
 81<procedure>(process-spawn MODE COMMAND [ARGUMENT-LIST [ENVIRONMENT-LIST [EXACT-FLAG]]])</procedure>
 82
 83Creates and runs a new process with the given {{COMMAND}} filename and
 84the optional {{ARGUMENT-LIST}} and {{ENVIRONMENT-LIST}}. {{MODE}}
 85specifies how exactly the process should be executed and must be one
 86or more of the {{spawn/...}} flags listed below.
 87
 88The {{EXACT-FLAG}}, default {{#f}}, controls quote-wrapping of
 89argument strings. When {{#t}} quote-wrapping is not performed.
 90
 91Returns:
 92* the exit status when synchronous
 93* the PID when asynchronous
 94* -1 when failure
 95
 96'''NOTE''': On all Unix-like builds (all except native MingW-based
 97Windows platforms), this procedure is unimplemented and will raise an
 98error.
 99
100<constant>spawn/overlay</constant>
101<constant>spawn/wait</constant>
102<constant>spawn/nowait</constant>
103<constant>spawn/nowaito</constant>
104<constant>spawn/detach</constant>
105
106These variables contains special flags that specify the exact
107semantics of {{process-spawn}}:
108
109* {{spawn/overlay}} replaces the current process with the new one.
110* {{spawn/wait}} suspends execution of the current process until the spawned process returns.
111* {{spawn/nowait}} does the opposite ({{spawn/nowaito}} is identical, according to the Microsoft documentation) and runs the process asynchronously.
112* {{spawn/detach}} runs the new process in the background, without being attached to a console.
113
114
115==== process-wait
116
117<procedure>(process-wait [PID [NOHANG]])</procedure>
118
119Suspends the current process until the child process with
120the id {{PID}} has terminated using the UNIX system call
121{{waitpid()}}. If {{PID}} is not given, then this procedure
122waits for any child process. If {{NOHANG}} is given and not
123{{#f}} then the current process is not suspended.  This procedure
124returns three values:
125
126* {{PID}} or 0, if {{NOHANG}} is true and the child process has not terminated yet.
127* {{#t}} if the process exited normally or {{#f}} otherwise.
128* either the exit status, if the process terminated normally or the signal number that terminated/stopped the process.
129
130Note that suspending the current process implies that all threads
131are suspended as well.
132
133On Windows, {{process-wait}} always returns {{#t}} for a terminated
134process and only the exit status is available. (Windows does not
135provide signals as an interprocess communication method.)
136
137
138==== process-sleep
139
140<procedure>(process-sleep SECONDS)</procedure>
141
142Puts the process to sleep for {{SECONDS}}. Returns either 0 if
143the time has completely elapsed, or the number of remaining seconds,
144if a signal occurred.
145
146
147==== process
148
149<procedure>(process COMMANDLINE)</procedure><br>
150<procedure>(process COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST])</procedure>
151
152Creates a subprocess and returns three values: an input port from
153which data written by the sub-process can be read, an output port from
154which any data written to will be received as input in the sub-process
155and the process-id of the started sub-process. Blocking reads and writes
156to or from the ports returned by {{process}} only block the current
157thread, not other threads executing concurrently.
158
159Standard error for the subprocess is linked up to the current
160process's standard error (see {{process*}} if you want to reify
161its standard error into a separate port).
162
163* The single parameter version passes the string {{COMMANDLINE}} to the host-system's shell that
164is invoked as a subprocess.
165* The multiple parameter version directly invokes the {{COMMAND}} as a subprocess. The {{ARGUMENT-LIST}}
166is directly passed, as is {{ENVIRONMENT-ALIST}}. These arguments have the same form as the ones of {{process-execute}}.
167
168Not using the shell may be preferrable for security reasons.
169
170Once both the input- and output ports are closed, an implicit
171{{waitpid(3)}} is done to wait for the subprocess to finish or to reap
172a subprocess that has terminated. If the subprocess has not finished,
173waiting for it will necessarily block all executing threads.
174
175==== process*
176
177<procedure>(process* COMMANDLINE)</procedure><br>
178<procedure>(process* COMMAND ARGUMENT-LIST [ENVIRONMENT-ALIST])</procedure>
179
180Like {{process}} but returns 4 values: an input port from
181which data written by the sub-process can be read, an output port from
182which any data written to will be received as input in the sub-process,
183the process-id of the started sub-process, and an input port from
184which data written by the sub-process to {{stderr}} can be read.
185
186=== Shell commands
187
188The commands below are all string-based.  This means you have to be
189very careful to properly quote any arguments to subprocesses, to avoid
190shell injection bugs which can lead to arbitrary code execution.
191
192You can quote arguments with the {{qs}} procedure, but it is strongly
193recommended you use {{fork}} with {{process-execute}} or the
194multi-argument versions of the {{process}}, {{process*}} or
195{{process-run}} procedures.
196
197==== qs
198
199<procedure>(qs STRING [PLATFORM])</procedure>
200
201Escapes {{STRING}} suitably for passing to a shell command on {{PLATFORM}}.
202{{PLATFORM}} defaults to the value of {{(build-platform)}} and indicates in
203which style the argument should be quoted. On Windows systems, the string
204is simply enclosed in double-quote ({{"}}) characters, on UNIXish systems,
205characters that would have a special meaning to the shell are escaped
206using backslash ({{\}}).
207
208
209==== system
210
211<procedure>(system STRING)</procedure>
212
213Execute shell command. The functionality offered by this procedure
214depends on the capabilities of the host shell. If the forking of a subprocess
215failed, an exception is raised. Otherwise the return status of the
216subprocess is returned unaltered.
217
218
219On a UNIX system, that value is the raw return value of waitpid(2), which contains signal, core dump and exit status.    It is 0 on success.  To pull out the signal number or exit status portably requires POSIX calls, but in a pinch you can use something like this: 
220
221<enscript highlight='scheme'>
222;; Returns two values: #t if the process exited normally or #f otherwise;
223;; and either the exit status, or the signal number if terminated via signal.
224(define (process-status rc)
225  (define (wait-signaled? x) (not (= 0 (bitwise-and x 127))))
226  (define (wait-signal x) (bitwise-and x 127))
227  (define (wait-exit-status x) (arithmetic-shift x -8))
228  (if (wait-signaled? rc)
229      (values #f (wait-signal rc))
230      (values #t (wait-exit-status rc))))
231
232#;> (process-status (system "exit 42"))
233#t
23442
235</enscript>
236
237==== system*
238
239<procedure>(system* STRING)</procedure>
240
241Similar to {{(system STRING)}}, but signals an error should the invoked
242program return a nonzero exit status.
243
244=== Pipes
245
246==== call-with-input-pipe
247==== call-with-output-pipe
248
249<procedure>(call-with-input-pipe CMDLINE PROC [MODE])</procedure><br>
250<procedure>(call-with-output-pipe CMDLINE PROC [MODE])</procedure>
251
252Call {{PROC}} with a single argument: a input- or output port
253for a pipe connected to the subprocess named in {{CMDLINE}}. If
254{{PROC}} returns normally, the pipe is closed and any result values
255are returned.
256
257==== close-input-pipe
258==== close-output-pipe
259
260<procedure>(close-input-pipe PORT)</procedure><br>
261<procedure>(close-output-pipe PORT)</procedure>
262
263Closes the pipe given in {{PORT}} and waits until the connected
264subprocess finishes. The exit-status code of the invoked process
265is returned.
266
267==== create-pipe
268
269<procedure>(create-pipe)</procedure>
270
271The fundamental pipe-creation operator. Calls the C function
272{{pipe()}} and returns 2 values: the file-descriptors of the input-
273and output-ends of the pipe.
274
275On Windows, there is an optional parameter {{MODE}}, which defaults
276to {{open/binary | open/noinherit}}. This can be {{open/binary}} or
277{{open/text}}, optionally or'ed with {{open/noinherit}}.
278
279
280==== open-input-pipe
281
282<procedure>(open-input-pipe CMDLINE [MODE])</procedure>
283
284Spawns a subprocess with the command-line string {{CMDLINE}} and
285returns a port, from which the output of the process can be read. If
286{{MODE}} is specified, it should be the keyword {{#:text}}
287(the default) or {{#:binary}}.
288
289==== open-output-pipe
290
291<procedure>(open-output-pipe CMDLINE [MODE])</procedure>
292
293Spawns a subprocess with the command-line string {{CMDLINE}} and
294returns a port. Anything written to that port is treated as the input
295for the process.  If {{MODE}} is specified, it should be the keyword
296{{#:text}} (the default) or {{#:binary}}.
297
298==== pipe/buf
299
300<constant>pipe/buf</constant>
301
302This variable contains the maximal number of bytes that can be written
303atomically into a pipe or FIFO.
304
305==== with-input-from-pipe
306==== with-output-to-pipe
307
308<procedure>(with-input-from-pipe CMDLINE THUNK [MODE])</procedure><br>
309<procedure>(with-output-to-pipe CMDLINE THUNK [MODE])</procedure>
310
311Temporarily set the value of
312{{current-input-port/current-output-port}} to a port for a
313pipe connected to the subprocess named in {{CMDLINE}} and call
314the procedure {{THUNK}} with no arguments. After {{THUNK}}
315returns normally the pipe is closed and the standard input-/output port
316is restored to its previous value and any result values are returned.
317
318<enscript highlight=scheme>
319(with-output-to-pipe
320  "gs -dNOPAUSE -sDEVICE=jpeg -dBATCH -sOutputFile=signballs.jpg -g600x600 -q -"
321  (lambda ()
322    (print #<<EOF
323 %!IOPSC-1993 %%Creator: HAYAKAWA Takashi<xxxxxxxx@xx.xxxxxx.xx.xx>
324 /C/neg/d/mul/R/rlineto/E/exp/H{{cvx def}repeat}def/T/dup/g/gt/r/roll/J/ifelse 8
325 H/A/copy(z&v4QX&93r9AxYQOZomQalxS2w!!O&vMYa43d6r93rMYvx2dca!D&cjSnjSnjjS3o!v&6A
326 X&55SAxM1CD7AjYxTTd62rmxCnTdSST0g&12wECST!&!J0g&D1!&xM0!J0g!l&544dC2Ac96ra!m&3A
327 F&&vGoGSnCT0g&wDmlvGoS8wpn6wpS2wTCpS1Sd7ov7Uk7o4Qkdw!&Mvlx1S7oZES3w!J!J!Q&7185d
328 Z&lx1CS9d9nE4!k&X&MY7!&1!J!x&jdnjdS3odS!N&mmx1C2wEc!G&150Nx4!n&2o!j&43r!U&0777d
329 ]&2AY2A776ddT4oS3oSnMVC00VV0RRR45E42063rNz&v7UX&UOzF!F!J![&44ETCnVn!a&1CDN!Y&0M
330 V1c&j2AYdjmMdjjd!o&1r!M){( )T 0 4 3 r put T(/)g{T(9)g{cvn}{cvi}J}{($)g[]J}J
331 cvx}forall/moveto/p/floor/w/div/S/add 29 H[{[{]setgray fill}for Y}for showpage
332 EOF
333 ) ) )
334</enscript>
335
336=== Windows specific notes
337
338Use of UTF8 encoded strings for pathnames is not supported. Windows
339uses a 16-bit UNICODE encoding with special system calls for
340wide-character support.  Only single-byte string encoding can be used.
341
342---
343Previous: [[Module (chicken pretty-print)]]
344
345Next: [[Module (chicken process signal)]]
Trap